package com.cpz.rabbitmq.config;

import com.cpz.rabbitmq.message.RabbitMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author cpz
 * @since 2022/09/19
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
public class RabbitConfig {

    /**
     * 配置生产者消息确认、回调函数
     * 回调函数调用情况：
     *         1、找不到交换机：ConfirmCallback
     *         2、找到交换机了，但是没找到队列：ConfirmCallback && ReturnsCallback
     *         3、交换机和队列啥都没找到：ConfirmCallback
     *         4、消息推送成功 ConfirmCallback
     * @param connectionFactory
     * @return
     */
    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        // 发送消息时强制回调，无论结果如何
        rabbitTemplate.setMandatory(true);

        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) ->
            log.info("【生产者】确认消息：ID：{}，结果：{}", correlationData.getId(), ack)
        );

        rabbitTemplate.setReturnsCallback(callback -> {
            RabbitMessage rabbitMessage = RabbitMessage.readObject(callback.getMessage());
            log.error("【生产者】回调消息：ID：{}，交换机：{}，路由键：{}，内容：{}，回应码：{}，回应信息：{}",
                    rabbitMessage.getMessageId(), rabbitMessage.exchange(), rabbitMessage.routingKey(), rabbitMessage.getData(), callback.getReplyCode(), callback.getReplyText());
        });

        return rabbitTemplate;
    }
}
